﻿#include "piechart.h"

PieChart::PieChart(QWidget* parent)
	: QWidget(parent)
{
	total_value = 0;
	start_angle = 100;
	i_radius = 30;
	o_radius = 60;
	rotate_animation = new QPropertyAnimation(this);
	rotate_animation->setTargetObject(this);
	rotate_animation->setDuration(1000);
	rotate_animation->setStartValue(start_angle);
	rotate_animation->setEndValue(start_angle + 360);
	cover_angle = start_angle;
	connect(rotate_animation, &QPropertyAnimation::valueChanged, this, [=](const QVariant& value)
		{
			cover_angle = value.toDouble();
			update();
		});
	connect(rotate_animation, &QPropertyAnimation::finished, this, [=]
		{
			offset_animation->start();
		});
	offset_animation = new QPropertyAnimation(this);
	offset_animation->setTargetObject(this);
	offset_animation->setDuration(300);
	offset_animation->setStartValue(0);
	offset_animation->setEndValue(10);
	m_offset = 0;
	connect(offset_animation, &QPropertyAnimation::valueChanged, this, [=](const QVariant& value)
		{
			m_offset = value.toInt();
			update();
		});
}

void PieChart::addData(const QString& desc, double value, const QColor& color)
{
	if (!chart_value.contains(desc))
		total_value += value;
	chart_value[desc] = value;
	chart_color[desc] = color;
}


void PieChart::paintEvent(QPaintEvent* event)
{
	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing);
	double sync_angle = start_angle;
	double span_angle;
	for (auto key : chart_value.keys())
	{
		span_angle = chart_value[key] / total_value * 360;
		double real_angle = sync_angle + span_angle > cover_angle ? cover_angle - sync_angle : span_angle;
		painter.setBrush(QBrush(chart_color[key]));
		//通过占比计算角度
		if (real_angle != 0)
		{
			//计算中间角度，并将区间设为[0，360)
			double degree = sync_angle + real_angle / 2;
			while (degree >= 360)
				degree -= 360;
			while (degree < 0)
				degree += 360;
			double radian = degree * (std::acos(-1) / 180.0);
			double cosabs;
			double sinabs;
			//painter.drawPie(QRect(width() / 2 - o_radius - m_offset, height() / 2 - o_radius - m_offset, (o_radius + m_offset) * 2, (o_radius + m_offset) * 2), sync_angle * 16, real_angle * 16);
			if (degree >= 0 && degree < 90)
			{
				cosabs = std::abs(std::cos(radian));
				sinabs = -std::abs(std::sin(radian));
			}
			if (degree >= 90 && degree < 180)
			{
				cosabs = -std::abs(std::cos(radian));
				sinabs = -std::abs(std::sin(radian));
			}
			if (degree >= 180 && degree < 270)
			{
				cosabs = -std::abs(std::cos(radian));
				sinabs = std::abs(std::sin(radian));
			}
			if (degree >= 270 && degree < 360)
			{
				cosabs = std::abs(std::cos(radian));
				sinabs = std::abs(std::sin(radian));
			}
			painter.drawPie(QRect(width() / 2 - o_radius + m_offset * cosabs, height() / 2 - o_radius + m_offset * sinabs, o_radius * 2, o_radius * 2), sync_angle * 16, real_angle * 16);
		}
		if (cover_angle < span_angle + sync_angle)
			break;
		sync_angle = sync_angle + span_angle;
	}
	painter.setBrush(QBrush(QColor(255, 255, 255)));
	//painter.setPen(QPen(QColor(255, 255, 255), 1));
	painter.drawEllipse(width() / 2 - i_radius - m_offset, height() / 2 - i_radius - m_offset, (i_radius + m_offset) * 2, (i_radius + m_offset) * 2);
}

void PieChart::mousePressEvent(QMouseEvent* event)
{
	m_offset = 0;
	rotate_animation->start();
}
